#include "ItemReference.h"
//#include "ItemReferenceFinder.h"

#include "Defines.h"
#include "CampaignItem.h"



#include <QCoreApplication>
#include <QTimer>
#include <QDebug>



namespace
{
QString REF_FIELD_NAME = "ref";
QString REF_TYPE_NAME = "type";

const char* TR_CONTEXT = "ItemReference";
const char* INVALID_REFERENCE_TEXT = QT_TRANSLATE_NOOP(TR_CONTEXT,"Invalid Reference");

const char* REF_TYPE_BONUS = QT_TRANSLATE_NOOP(TR_CONTEXT,"Bonus");
const char* REF_TYPE_SYNERGY = QT_TRANSLATE_NOOP(TR_CONTEXT,"Synergy");
const char* REF_TYPE_GROUP = QT_TRANSLATE_NOOP(TR_CONTEXT,"Group");
const char* REF_TYPE_REQUIREMENT = QT_TRANSLATE_NOOP(TR_CONTEXT,"Requirement");
}


ItemReference::ItemReference(AbstractItem* parent)
    : Item("Reference", parent)
{
    d = new Data();
    setData(TypeData, BonusRef);
    setData(CategoryData, ItemCategory_Reference);
}


ItemReference::~ItemReference()
{
}



QString ItemReference::typeName(const int& ref_type)
{
    switch (ref_type)
    {
    case BonusRef:
        return qApp->translate(TR_CONTEXT, REF_TYPE_BONUS);

    case SynergyRef:
        return qApp->translate(TR_CONTEXT, REF_TYPE_SYNERGY);


    case GroupRef:
        return qApp->translate(TR_CONTEXT, REF_TYPE_GROUP);

    case RequirementRef:
        return qApp->translate(TR_CONTEXT, REF_TYPE_REQUIREMENT);
    }

    return QString::null;
}



bool ItemReference::isValid() const
{
    if (d->refItem.isNull()) return false;
    if (d->refName.isEmpty()) return false;
    if (d->refName != d->refItem->objectName()) return false;

    return true;
}



int ItemReference::fieldCount() const
{
    return (ItemReference::DataType_LAST - AbstractItem::DataType_FIRST + 1);
}



QString ItemReference::fieldName(const int &data_type) const
{
    switch (data_type)
    {
    case RefData:   return REF_FIELD_NAME;
    case TypeData:  return REF_TYPE_NAME;
    default:        return Item::fieldName(data_type);
    }

    return QString::null;
}



int ItemReference::field(const QString &field_name) const
{
    if (field_name.toLower() == REF_FIELD_NAME.toLower())   return RefData;
    if (field_name.toLower() == REF_TYPE_NAME.toLower())    return TypeData;

    return Item::field(field_name);
}



QString ItemReference::referencedName() const
{
    return data(RefData).toString();
}



AbstractItem* ItemReference::referencedItem() const
{
    return d->refItem.data();
}



void ItemReference::onRefreshReferenceItem()
{
    if (!d->refItem.isNull())
    {
        disconnect(d->refItem.data(), SIGNAL(sigDirty()), this, SLOT(onReferenceItemDirty()));
    }


    AbstractItem* refItem = rootItem()->findChild<AbstractItem*>(d->refName);
    if (!refItem)
    {
        d->refName = QString::null;
        d->refItem = 0;
        emit sigDirty();
        return;
    }

    if (!parent() || refItem == parent()) return;

    foreach (QObject* obj, parent()->children())
    {
        ItemReference* otherRefItem = dynamic_cast<ItemReference*>(obj);
        if (!otherRefItem) continue;

        if (otherRefItem->referencedItem() == refItem) return;
    }

    d->refItem = refItem;
    d->refName = refItem->objectName();

    connect(d->refItem.data(), SIGNAL(sigDirty()), this, SLOT(onReferenceItemDirty()));
}



void ItemReference::onReferenceItemDirty()
{
    if (d->refItem.isNull()) return;

    d->refName = d->refItem->objectName();
}



QVariant ItemReference::customData(const int &data_type, int role) const
{
    switch (data_type)
    {
    case TypeData:
        {
            if (role == Qt::EditRole) return d->refType;
            if (role == Qt::DisplayRole) return typeName(d->refType.toInt());

            break;
        }
    case RefData:
        {

            if (role == Qt::EditRole) return d->refName;

            if (role != Qt::DisplayRole)  return QVariant();

            if (!isValid()) return tr("Invalid Reference");

            return d->refItem->name();
        }
    case ValueData:
        {
            return Item::customData(data_type);
        }
    }

    return QVariant();
}



void ItemReference::setCustomData(const int &data_type, const QVariant &value)
{
    switch (data_type)
    {
    case RefData:
        if (value.toString() == INVALID_REFERENCE_TEXT) return;
        if (d->refName == value.toString()) return;

        d->refName = value.toString();
        QTimer::singleShot(0, this, SLOT(onRefreshReferenceItem()));
        return;

    case TypeData:
        if (value.toInt() < ReferenceType_FIRST || value.toInt() > ReferenceType_LAST) return;
        d->refType = value;
        return;

    case ValueData:
        Item::setCustomData(data_type, value);
        return;

    default:
        return;
    }


}



